/*
STL 常用算法 遍历算法
概述
  算法主要由头文件<algorithm> <functional> <numeric>组成
  <algorithm>是所有STL头文件中最大的一个，涉及到比较、交换、查找、遍历、复制、修改等等
  <numeric>体积很小，只包括几个在序列上面进行简单数学运算的模板函数
  <functional>定义了一些模板类，用以什么函数对象

常用遍历算法简介
  for_each  // 遍历容器
  transform  // 搬运容器到另一个容器

函数原型
  for_each(iterator beg, iterator, end, _func); // [beg, end), _func 函数或者函数对象
  transform(iterator beg1, iterator end1, iterator beg2, _func);  // [beg1, end1)源容器区间， beg2 目标容器开始迭代器位置， _func 函数或者函数对象

*/

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

// for_each 算法
// 普通函数
void print01(int val)
{
    cout << val << " ";
}

// 函数对象
class print02
{
public:
    void operator()(int val)
    {
        cout << val << " ";
    }
};

void test01()
{
    cout << "------------------- for_each ------------------" << endl;
    vector<int> v = {3, 5, 0, 8, 2, 4};

    cout << "common fun -> ";
    for_each(v.begin(), v.end(), print01); // 使用普通函数
    cout << endl;

    cout << "fun object -> ";
    for_each(v.begin(), v.end(), print02()); // 使用函数对象
    cout << endl;
}

// transform
// 普通函数
int plus01(int val)
{
    return val + 100;
}

// 函数对象
class TransForm
{
public:
    int operator()(int val)
    {
        return val + 100;
    }
};

void test02()
{
    cout << "------------------- transform ------------------" << endl;
    cout << "original vector -> ";
    vector<int> v = {1, 2, 3, 4, 5};  // 源容器
    for_each(v.begin(), v.end(), print01);
    cout << endl;

    cout << "common fun -> ";
    vector<int>v1;  // 目标容器
    v1.resize(v.size());  // 目标容器需要提前开辟空间
    transform(v.begin(), v.end(), v1.begin(), plus01);  // 使用普通函数
    for_each(v1.begin(), v1.end(), print01);
    cout << endl;

    cout << "fun object -> ";
    vector<int>v2;  // 目标容器
    v2.resize(v.size());  // 目标容器需要提前开辟空间
    transform(v.begin(), v.end(), v2.begin(), plus01);  // 使用普通函数
    for_each(v2.begin(), v2.end(), print01);
    cout << endl;
}

int main()
{
    test01(); // for_each
    test02(); // transform 
}